from __future__ import print_function

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty,\
    NumericProperty, BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.button import Button
from kivy.clock import Clock

from pypump.models.image import Image as PumpImage
from goblinoid.services.thread_queue import ThreadQueue
from goblinoid.services.login_service import remove_credential
from goblinoid.libs.toast import toast
import threading

Builder.load_file('goblinoid/profile/profilepanel.kv')


class ProfilePanel(BoxLayout):
    profile = ObjectProperty(None)
    outbox = ObjectProperty(None)
    posts = NumericProperty(0)
    username = StringProperty()
    queue = ObjectProperty()
    activity_thread = ObjectProperty()
    post_index = NumericProperty(0)
    already_fetching = BooleanProperty(False)

    activity_scroll_view = ObjectProperty(None)
    activity_grid = ObjectProperty()

    def __init__(self, **kwargs):
        super(ProfilePanel, self).__init__(**kwargs)
        self.queue = ThreadQueue(self.add_activity_item)
        Clock.schedule_interval(self.ensure_scroll_y_trigger, 0.5)
        toast('loading...', True)

    def on_profile(self, instance, profile):
        try:
            self.activity_grid.bind(minimum_height=self.activity_grid.setter(
                'height'))
            self.outbox = profile.outbox
            self.username = unicode(profile.username)
        except KeyError, e:
            print('KeyError: {0}'.format(e))

    def on_outbox(self, instance, outbox):
        self.fetch_posts()

    def fetch_posts(self):
        if not self.already_fetching:
            self.already_fetching = True
            self.activity_thread = FetchPosts(self.outbox, self.post_index, 20, self.queue)
            self.activity_thread.start()
            self.post_index += 20

    def evaluate_prefetch(self, scroll_y):
        if self.posts != 0:
            if scroll_y < 1/(float(self.posts) ** (1.0/3)):
                self.fetch_posts()

    def add_activity_item(self):
        while True:
            try:
                key, activity = self.queue.get()
                if key == 'done':
                    self.already_fetching = False
                    break
                else:
                    self.posts += 1
                    activity_item = RecentActivityItem(
                        image_source=activity.obj.thumbnail.url)
                    self.activity_grid.add_widget(activity_item)
            except:
                break

    def ensure_scroll_y_trigger(self, instance):
        if self.activity_grid and self.activity_scroll_view is not None:
            if self.activity_grid.height <= self.activity_scroll_view.height:
                self.fetch_posts()


class FetchPosts(threading.Thread):

    def __init__(self, outbox, index, batch, queue, **kwargs):
        threading.Thread.__init__(self)
        self.outbox = outbox
        self.index = index
        self.batch = batch
        self.queue = queue

    def run(self):
        current_index = self.index
        for activity in self.outbox.major[self.index: self.index+self.batch]:
            if isinstance(activity.obj, PumpImage):
                current_index += 1
                self.queue.put(current_index, activity)
        self.queue.put('done', None)
        self.is_running = False


class ProfileFeed(ScrollView):

    user_height = NumericProperty(0)
    container_height = NumericProperty(0)

    def on_container_height(self, instance, height):
        if height != 0:
            self.scroll_y = 1 - self.user_height / height
        else:
            self.scroll_y = 1

    def on_scroll_y(self, instance, scroll_y):
        self.user_height = (1 - scroll_y) * self.container_height


class RecentActivityItem(BoxLayout):
    image_source = StringProperty()


class ProfileHeader(BoxLayout):
    username = StringProperty()
    posts = NumericProperty(0)
    followers = NumericProperty(0)
    following = NumericProperty(0)

    def __init__(self, **kwargs):
        super(ProfileHeader, self).__init__(**kwargs)

    def on_username(self, instance, username):
        if username == App.get_running_app().pump_service.pump.me.username:
            self.ids.profile_stats.add_widget(LogOutButton())


class LogOutButton(Button):

    def log_out(self):
        print('logging out...')
        remove_credential(App.get_running_app().pump_service.data_dir)
        App.get_running_app().open_view('login', True)
        App.get_running_app().pump_service.feed_data = []
